package com.blackhorse.controller;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

/**
 * spring mvc文件上传
 */
@Controller
@RequestMapping("/upload")
public class UploadController {

    /**
     * 传统方式解析上传文件，需要commons-fileupload和commons-io组件
     *
     * @return
     */
    @RequestMapping("/fileupload1")
    public void fileupload(HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("文件上传...");
        //使用commons-fileupload组件完成文件上传
        //1.上传位置
        String path = request.getSession().getServletContext().getRealPath("/upload/");
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();//如果不存在，创建文件夹
        }

        //2.解析request，获取上传文件项
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        List<FileItem> items = upload.parseRequest(request);
        //3.遍历文件项
        for (FileItem item : items) {
            //判断当前item是否是上传文件
            if (item.isFormField()) {
                //是普通表单项
            } else {
                //4.是上传文件项
                //4.1获取上传文件名
                String filename = item.getName();
                //4.2把文件名设为唯一值，防止重复上传同名文件导致覆盖
                String uuid = UUID.randomUUID().toString().replace("-", "");
                filename = uuid + "_" + filename;
                //5.完成文件上传
                item.write(new File(path, filename));
                //6.删除临时文件（当上传文件大于10kB，会产生磁盘临时文件，小于10KB会在内存创建缓存）
                item.delete();
            }
        }
        request.getRequestDispatcher("/WEB-INF/pages/upload_success.jsp").forward(request, response);
    }

    /**
     * spring mvc方式上传文件，需要在springmvc.xml中配置文件解析器
     * MultipartFile 参数的名称必须和表单中文件项name值相同
     */
    @RequestMapping("/fileupload2")
    public String fileupload2(HttpServletRequest request, MultipartFile upload) throws IOException {
        System.out.println("spring mvc文件上传...");
        //1.上传位置
        String path = request.getSession().getServletContext().getRealPath("/upload/");
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();//如果不存在，创建文件夹
        }
        //2.获取文件名
        String filename = upload.getOriginalFilename();
        //2.1把文件名设为唯一值，防止重复上传同名文件导致覆盖
        String uuid = UUID.randomUUID().toString().replace("-", "");
        filename = uuid + "_" + filename;

        //3.完成上传
        upload.transferTo(new File(path, filename));
        return "upload_success";
    }


    /**
     * 跨服务器上传（了解），该项目为应用服务器（接受用户请求），eclipse项目为文件服务器（存储上传文件）
     * 需要导入jersey的jar包
     */
    @RequestMapping("/fileupload3")
    public String fileupload3(MultipartFile upload) throws IOException {
        System.out.println("spring mvc跨服务器上传...");
        //1.上传位置
        //定义文件服务器路径（eclipse的SpringMVC FileServer项目路径）
        String path = "http://localhost:8888/fileserver/upload";

        //2.获取文件名
        String filename = upload.getOriginalFilename();
        //2.1把文件名设为唯一值，防止重复上传同名文件导致覆盖
        String uuid = UUID.randomUUID().toString().replace("-", "");
        filename = uuid + "_" + filename;

        //3.完成上传
        //3.1创建客户端对象
        Client client = Client.create();
        //3.2和文件服务器连接
        WebResource resource = client.resource(path + "/" + filename);
        //3.3上传文件
        resource.put(upload.getBytes());

        return "upload_success";
    }
}
